﻿using MCPlatform.Dxf.Utils;
using netDxf;
using netDxf.Entities;
using System;
using System.Linq;
using System.Windows.Media;

namespace MCPlatform.Dxf.Entities
{
    public class SplinePathEntity : PathEntityBase
    {
        public List<Vector3> ControlPoints { get; } // 样条曲线的控制点  
        public int Degree { get; } // 样条曲线的次数  

       
        public Spline Spline { get; }

        public SplinePathEntity(Spline spline)
        {
            Spline = spline;
            Type = spline;
            Handle = spline.Handle;
            Degree = spline.Degree;
            ControlPoints = spline.ControlPoints.ToList();
            CalculatePoint(spline);
            DrawShape(spline);
            GetPoint(spline);
        }

        public void DrawShape(Spline? spline, float scaleX = 1, float scaleY = 1, float strokeThickness = 1)
        {
            // 如果 polyLine 为空，则使用默认的 polyLine
            if (spline == null)
            {
                spline = this.Spline;
            }


            // 将控制点转换为System.Windows.Point[]
            System.Windows.Point[] controlPoints = spline.ControlPoints.Select(v => new System.Windows.Point(v.X, v.Y)).ToArray();
        
            // 计算样条曲线的点
            System.Windows.Point[] splinePoints = InterpolateSpline(controlPoints, spline.ControlPoints.Length);

            // 创建Polyline对象
            System.Windows.Shapes.Polyline  polyline = new System.Windows.Shapes.Polyline
            {
                Stroke = Utility.ConvertAciColorToBrush(spline.Color),
                StrokeThickness = Utility.GetNumberFromTextToFloat(spline.Lineweight.ToString(), spline.Layer.Lineweight.ToString()) ?? strokeThickness,
            };




            foreach (var point in splinePoints)
            {
                polyline.Points.Add(point);
            }



            this.Shape = polyline;
            this.Shape.Tag = spline.Handle;

        }

        public void CalculatePoint(Spline spline)
        {
            if (spline.ControlPoints.Length > 0)
            {
                StartPoint = new netDxf.Vector3()
                {
                    X = spline.ControlPoints[0].X,
                    Y = spline.ControlPoints[0].Y,
                };


                int middleIndex = spline.ControlPoints.Length / 2;

                MidPoint = new netDxf.Vector3()
                {
                    X = spline.ControlPoints.ElementAt(middleIndex).X,
                    Y = spline.ControlPoints.ElementAt(middleIndex).Y,
                };




                EndPoint = new netDxf.Vector3()
                {
                    X = spline.ControlPoints.Last().X,
                    Y = spline.ControlPoints.Last().Y,
                };
            }
        }

        public void GetPoint(Spline spline)
        {
            if (spline.ControlPoints.Length > 0)
            {

                PointsList = new List<netDxf.Vector3>();
                foreach (var vertex in spline.ControlPoints)
                {
                    var Point = new netDxf.Vector3()
                    {
                        X = vertex.X,
                        Y = vertex.Y,
                        Z = 0
                    };

                    PointsList.Add(Point);
                }



                if (spline.IsClosed)
                {
                    var Point = new netDxf.Vector3()
                    {
                        X = spline.ControlPoints[0].X,
                        Y = spline.ControlPoints[0].Y,
                        Z = 0
                    };

                    PointsList.Add(Point);

                }
            }
        }

        private System.Windows.Point[] InterpolateSpline(System.Windows.Point[] controlPoints, int numPoints)
        {
            // 使用一个简单的线性插值（可以替换为更高级的样条曲线插值算法）
            System.Windows.Point[] splinePoints = new System.Windows.Point[numPoints];
            for (int i = 0; i < numPoints; i++)
            {
                double t = (double)i / (numPoints - 1);
                splinePoints[i] = LinearInterpolate(controlPoints, t);
            }
            return splinePoints;
        }

        private System.Windows.Point LinearInterpolate(System.Windows.Point[] points, double t)
        {
            int n = points.Length - 1;
            int i = (int)(t * n);
            double localT = (t * n) - i;
            if (i >= n) i = n - 1; // 边界处理
            return new System.Windows.Point(
                (1 - localT) * points[i].X + localT * points[i + 1].X,
                (1 - localT) * points[i].Y + localT * points[i + 1].Y
            );
        }
    }
}
